﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows.Data;
using QuailDashboard.View.Helpers;
using QuailDashboard.View.Models;
using QuailDashboard.View.QuailServiceReference;

namespace QuailDashboard.View.Converters
{

    /// <summary>
    /// Converts quail status id to text
    /// </summary>
    public class StatusIdConverter : IValueConverter
    {
        private static readonly Dictionary<int, StringModel> DictionaryStatusReference = new Dictionary<int, StringModel>();
        private static bool _dictionaryReadInProcess;

        /// <summary>
        /// Modifies the source data before passing it to the target for display in the UI.
        /// </summary>
        /// <returns>
        /// The value to be passed to the target dependency property.
        /// </returns>
        /// <param name="value">The source data being passed to the target.</param>
        /// <param name="targetType">The <see cref="T:System.Type"/> of data expected by the target dependency property.</param>
        /// <param name="parameter">An optional parameter to be used in the converter logic.</param>
        /// <param name="culture">The culture of the conversion.</param>
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is int)
            {
                var ivalue = (int) value;

                lock (DictionaryStatusReference)
                {
                    if (DictionaryStatusReference.Count == 0 && !_dictionaryReadInProcess)
                    {
                        var data = QuailDataServiceFactory.CreateClient();
                        data.GetTaskStatusesCompleted += OnTaskStatusesCompleted;
                        data.GetTaskStatusesAsync();
                        _dictionaryReadInProcess = true;
                    }

                    StringModel result;
                    if (!DictionaryStatusReference.TryGetValue(ivalue, out result))
                    {
                        result = new StringModel(value.ToString());
                        DictionaryStatusReference.Add(ivalue, result);
                    }

                    return result;
                }
            }

            return null;
        }

        /// <summary>
        /// Modifies the target data before passing it to the source object.  This method is called only in <see cref="F:System.Windows.Data.BindingMode.TwoWay"/> bindings.
        /// </summary>
        /// <returns>
        /// The value to be passed to the source object.
        /// </returns>
        /// <param name="value">The target data being passed to the source.</param><param name="targetType">The <see cref="T:System.Type"/> of data expected by the source object.</param><param name="parameter">An optional parameter to be used in the converter logic.</param><param name="culture">The culture of the conversion.</param>
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        private static void OnTaskStatusesCompleted(object sender, GetTaskStatusesCompletedEventArgs e)
        {
            lock (DictionaryStatusReference)
            {
                _dictionaryReadInProcess = false;

                if (e.Error == null)
                {
                    foreach (var status in e.Result)
                    {
                        if (DictionaryStatusReference.ContainsKey(status.TaskStatusId))
                            DictionaryStatusReference[status.TaskStatusId].Value = status.TaskStatus1;
                        else
                            DictionaryStatusReference.Add(status.TaskStatusId, new StringModel(status.TaskStatus1));
                    }
                }
            }
        }

        public class StringModel : Model
        {
            private string _value;

            public StringModel(string value)
            {
                _value = value;
            }

            public string Value
            {
                get
                {
                    return _value;
                }

                set
                {
                    _value = value;
                    NotifyPropertyChanged();
                }
            }

            public override string ToString()
            {
                return Value;
            }
        }
    }
}
